package implicits

import scala.annotation.tailrec

/**
 * Created by Administrator on 2019/11/13
 */

trait MyListTool extends MyTupleTool with  shared.implicits.MyMapTool {

  implicit class MyList[T](list: List[T]) {

    def distinctBy[B](f: T => B) = {
      list.map { x =>
        (f(x), x)
      }.toMap.values.toList
    }

    def distinctByKeepHead[B](f: T => B): List[T] = {

      def loop(list: List[T], acc: (List[T], Set[B])): (List[T], Set[B]) = {
        list match {
          case Nil => acc
          case x :: xs =>
            val key = f(x)
            val (list, set) = acc
            if (!set.contains(key)) {
              loop(xs, (list ::: List(x), set + (key)))
            } else loop(xs, acc)
        }
      }

      loop(list, (List[T](), Set[B]()))._1
    }

    def distinctByKeepLast[B](f: T => B) = {
      list.groupBy(f(_)).valueList.map(_.last)
    }

    def removed(i: Int) = {
      list.zipWithIndex.filterNot { case (v, curI) =>
        curI == i
      }.map(_._1)
    }

    def subtractOne(x: T) = {
      val i = list.indexOf(x)
      if (i != -1) {
        removed(i)
      } else list
    }

    def subtractAll(xs: List[T]) = {
      list.filterNot { x =>
        xs.contains(x)
      }
    }

    def getOrElse(i: Int, default: T) = {
      if (list.isDefinedAt(i)) {
        list(i)
      } else default
    }

    def get(i: Int) = {
      if (list.isDefinedAt(i)) {
        Some(list(i))
      } else None
    }

    def optionMap = {
      list.map { x =>
        (x -> x)
      }.toSeqMap
    }

  }


}
